/*
 *  Copyright 2005 Blandware (http://www.blandware.com)
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.blandware.atleap.service.questionnaire;

import com.blandware.atleap.common.util.PartialCollection;
import com.blandware.atleap.common.util.QueryInfo;
import com.blandware.atleap.model.questionnaire.Question;
import com.blandware.atleap.model.questionnaire.Questionnaire;
import com.blandware.atleap.model.questionnaire.AnswerOption;
import com.blandware.atleap.model.questionnaire.FilledQuestionnaire;
import com.blandware.atleap.persistence.exception.DeleteException;
import com.blandware.atleap.service.core.BaseManager;
import com.blandware.atleap.service.exception.BeanAlreadyExistsException;
import com.blandware.atleap.service.exception.BeanNotFoundException;
import com.blandware.atleap.service.exception.OwnerNotFoundException;

import java.util.Map;

/**
 * <p>Business Delegate (Proxy) Interface to handle communication between web and
 * persistence layer.
 * </p>
 * <p><a href="QuestionnaireManager.java.html"><i>View source</i></a></p>
 *
 * @author Roman Puchkovskiy <a href="mailto:roman.puchkovskiy@blandware.com">
 *         &lt;roman.puchkovskiy@blandware.com&gt;</a>
 * @version $Revision: 1.3 $ $Date: 2006/10/31 11:55:54 $
 */
public interface QuestionnaireManager extends BaseManager {

    // Q U E S T I O N N A I R E S

	//~ CRUD Methods ================================================================

	/**
	 * Creates a questionnaire.
	 *
	 * @param questionnaire      Questionnaire to create
	 * @param linkedObjects Map of pairs <code>uri -&gt; object<code>, which
     *                      link URI in the annotation to
	 *                      corresponding object (resource or page) if it exists
	 * @return ID of created questionnaire
	 * @throws com.blandware.atleap.service.exception.BeanAlreadyExistsException
	 *          if linkable item with same URI already exists
	 */
	public Long createQuestionnaire(Questionnaire questionnaire,
                                    Map linkedObjects)
            throws BeanAlreadyExistsException;

	/**
	 * Retrieves questionnaire with specified ID.
	 *
	 * @param questionnaireId The ID of questionnaire to retrieve
	 * @return Questionnaire or null if no questionnaire with specified ID
     * exists in database
	 */
	public Questionnaire retrieveQuestionnaire(Long questionnaireId);

	/**
	 * Updates a questionnaire.
	 *
	 * @param questionnaire      Questionnaire to update
	 * @param linkedObjects Map of pairs <code>uri -&gt; object<code>, which
     *                      link URI in the annotation to
	 *                      corresponding object (resource or page) if it exists
	 * @throws com.blandware.atleap.service.exception.BeanAlreadyExistsException
	 *          if page with same URI already
     *          exists
	 */
	public void updateQuestionnaire(Questionnaire questionnaire,
                                    Map linkedObjects)
            throws BeanAlreadyExistsException;

	/**
	 * Updates questionnaire without changing links to pages or resources from
     * internal content field values.
	 *
	 * @param questionnaire      Questionnaire to update
	 * @throws com.blandware.atleap.service.exception.BeanAlreadyExistsException
	 *          if page (no matter content or action) with same URI already exists
	 */
	public void updateQuestionnaire(Questionnaire questionnaire)
            throws BeanAlreadyExistsException;

	/**
	 * Removes a questionnaire.
	 *
	 * @param questionnaireId ID of questionnaire to remove
	 * @throws com.blandware.atleap.persistence.exception.DeleteException
     *                          if questionnaire cannot be deleted
	 * @throws com.blandware.atleap.service.exception.BeanNotFoundException
     * if questionnaire with specified ID was not found
	 */
	public void deleteQuestionnaire(Long questionnaireId)
            throws DeleteException, BeanNotFoundException;

	// ~ Additional methods ================================================================

	/**
	 * Retrieves filtered/sorted collection of questionnaires.
	 *
	 * @param queryInfo Object that contains information about how to filter
     * and sort data
	 * @return Collection of questionnaires
	 */
	public PartialCollection listQuestionnaires(QueryInfo queryInfo);

    /**
     * Creates a copy of a questionnaire making it unfixed and inactive.
     * Copy URI is made of initial questionnaire URI with '_copy' appended.
     *
     * @param questionnaire questionnaire to copy
     * @param suffixMap map of content locale identifiers to suffixes which
     * will be added to copy title
     * @return new questionnaire
     */
    public Questionnaire copyQuestionnaire(Questionnaire questionnaire,
                                           Map suffixMap);

    // Q U E S T I O N S

    //~ CRUD Methods ================================================================

    /**
     * Creates new question.
     *
     * @param question   question to create
     * @param questionnaireId ID of owner questionnaire
     * @return ID of created question
     * @throws BeanNotFoundException      if questionnaire with specified ID
     * couldn't be found
     * @throws BeanAlreadyExistsException if such question already exists
     */
    public Long createQuestion(Question question, Long questionnaireId)
            throws BeanNotFoundException, BeanAlreadyExistsException;

    /**
     * Retrieves question with specified ID.
     *
     * @param questionId the ID of question to retrieve
     * @return Question or null if no question with specified ID exists in
     * database
     */
    public Question retrieveQuestion(Long questionId);

    /**
     * Updates question.
     *
     * @param question         question to update
     * @param questionnaireId ID of questionnaire to associate field with
     * @throws BeanNotFoundException      if questionnaire with specified ID
     * couldn't be found
     * @throws BeanAlreadyExistsException if such question already
     */
    public void updateQuestion(Question question, Long questionnaireId)
            throws BeanNotFoundException, BeanAlreadyExistsException;


    /**
     * Removes question.
     *
     * @param questionnaireId ID of question to remove
     * @throws BeanNotFoundException if question with specified ID couldn't be
     * found
     * @throws DeleteException       if question cannot be deleted
     */
    public void deleteQuestion(Long questionnaireId)
            throws BeanNotFoundException, DeleteException;

    // ~ Additional methods ================================================================

    /**
     * Retrieves filtered/sorted collection of questions.
     *
     * @param queryInfo Object that contains information about how to filter
     * and sort data
     * @return Collection of questions
     */
    public PartialCollection listQuestions(QueryInfo queryInfo);

    /**
     * Changes question position.
     *
     * @param question question to move
     * @param up whether question should raise in the list
     */
    public void moveQuestion(Question question, boolean up);

    /**
     * Returns least and most positions of question which owner has given ID.
     *
     * @param ownerId ID of questionnaire which children will be considered
     * @return wto-element array: least and most occupied positions
     */
    public Integer[] getQuestionFirstLastOccupiedPositions(Long ownerId);

    // A N S W E R   O P T I O N S

    //~ CRUD Methods ================================================================

    /**
     * Creates new answer option.
     *
     * @param answerOption   answerOption to create
     * @param questionId ID of owner question
     * @return ID of created answerOption
     * @throws BeanNotFoundException      if question with specified ID
     * couldn't be found
     * @throws BeanAlreadyExistsException if such answerOption already exists
     */
    public Long createAnswerOption(AnswerOption answerOption, Long questionId)
            throws BeanNotFoundException, BeanAlreadyExistsException;

    /**
     * Retrieves answer option with specified ID.
     *
     * @param answerOptionId the ID of option to retrieve
     * @return AnswerOption or null if no option with specified ID exists in
     * database
     */
    public AnswerOption retrieveAnswerOption(Long answerOptionId);

    /**
     * Updates answer option.
     *
     * @param answerOption         answerOption to update
     * @param questionId ID of question to associate field with
     * @throws BeanNotFoundException      if question with specified ID
     * couldn't be found
     * @throws BeanAlreadyExistsException if such answerOption already exists
     */
    public void updateAnswerOption(AnswerOption answerOption, Long questionId)
            throws BeanNotFoundException, BeanAlreadyExistsException;

    /**
     * Removes answer option.
     *
     * @param answerOptionId ID of answer option to remove
     * @throws BeanNotFoundException if answer option with specified ID couldn't
     * be found
     * @throws DeleteException       if answer option cannot be deleted
     */
    public void deleteAnswerOption(Long answerOptionId)
            throws BeanNotFoundException, DeleteException;

    // ~ Additional methods ================================================================

    /**
     * Retrieves filtered/sorted collection of answer options.
     *
     * @param queryInfo Object that contains information about how to filter
     * and sort data
     * @return Collection of answer options
     */
    public PartialCollection listAnswerOptions(QueryInfo queryInfo);

    /**
     * Changes answer option position.
     *
     * @param answerOption answerOption to move
     * @param up whether answerOption should raise in the list
     */
    public void moveAnswerOption(AnswerOption answerOption, boolean up);

    /**
     * Returns least and most positions of answer option which owner has
     * given ID.
     *
     * @param ownerId ID of question which children will be considered
     * @return two-element array: least and most occupied positions
     */
    public Integer[] getAnswerOptionFirstLastOccupiedPositions(Long ownerId);

    // F I L L E D   Q U E S T I O N N A I R E S

    //~ CRUD Methods ================================================================

    /**
     * Creates a filled questionnaireId.
     *
     * @param filledQuestionnaire filled questionnaireId to create
     * @param questionnaireId ID of questionnaire to which it belongs
     * @return ID of created entity
     */
    public Long createFilledQuestionnaire(FilledQuestionnaire filledQuestionnaire,
                                          Long questionnaireId)
            throws OwnerNotFoundException;

    /**
     * Retrieves a filled questionnaire by its ID.
     *
     * @param filledQuestionnaireId ID of filled questionnaire to retrieve
     * @return retrieved filled questionnaire
     */
    public FilledQuestionnaire retrieveFilledQuestionnaire(Long filledQuestionnaireId);

    /**
     * Deletes a filled questionnaire.
     *
     * @param filledQuestionnaireId ID of filled questionnaire to delete
     */
    public void deleteFilledQuestionnaire(Long filledQuestionnaireId)
            throws BeanNotFoundException;

	// ~ Additional methods ================================================================

	/**
	 * Retrieves filtered/sorted collection of filled questionnaires.
	 *
	 * @param queryInfo Object that contains information about how to filter
     * and sort data
	 * @return Collection of filled questionnaires
	 */
	public PartialCollection listFilledQuestionnaires(QueryInfo queryInfo);
}